# -*- coding: utf-8 -*-
from PySide.QtCore import Slot as Slot, Signal as Signal, QSize
from PySide.QtGui import QMainWindow, QFileDialog, QFontDialog, QApplication, QMessageBox
from PySide.QtGui import QFont, QColor, QTextCharFormat, QPalette

from FileEditor_ui import Ui_FileEditor
from FindDialog import FindDialog
from about import AboutDialog
from opt import codeOpt
from opt import fileOpt


class MainWindow(QMainWindow):
    __file_path = ""
    __tittle = "FileEditor"
    __file_encode = "utf-8"
    __code_dict = {"ascii": 0, "GB18030": 1, "utf-8": 2}
    __text_font = QFont("Arial", 14, QFont.Bold, italic=True)
    __format = QTextCharFormat()

    __text_high_lighted_text_color = QColor(0xff, 0xff, 0x00)
    __text_high_lighted_bg_color = QColor(0x00, 0x00, 0xff)
    __text_base_color = QColor(255, 233, 198)
    __text_bg_color = QColor(0x00, 0x77, 0x00)
    __text_text_color = QColor(0x00, 0x00, 0x00)

    __text_palette = QPalette()
    # __text_palette.setColor(QPalette.HighlightedText, __text_high_lighted_text_color)
    # __text_palette.setColor(QPalette.Highlight, __text_high_lighted_bg_color)
    __text_palette.setColor(QPalette.Base, __text_base_color)
    __text_palette.setColor(QPalette.Background, __text_bg_color)
    __text_palette.setColor(QPalette.Text, __text_text_color)

    # __window_palette=QPalette()
    # __window_palette.setColor(QPalette.Window,QColor(0,255,255))


    # init
    def __init__(self, args):
        QMainWindow.__init__(self)
        try:
            self.setAcceptDrops(True)
            self.ui = Ui_FileEditor()
            self.ui.setupUi(self)
            self.ui.toolBar.addWidget(self.ui.code)
            self.ui.centralwidget = self.ui.plainTextEdit
            self.ui.plainTextEdit.setFont(self.__text_font)
            self.ui.plainTextEdit.setAcceptDrops(True)
            self.ui.plainTextEdit.setPalette(self.__text_palette)
            self.ui.code.setCurrentIndex(self.__code_dict[self.__file_encode])
            # self.setPalette(self.__window_palette)
            self.opened.connect(self.hehe)
            self.new()
            if len(args) > 1:
                self.__open(args[1].decode("GB2312"))
        except Exception as e:
            self.except_(e)

    # option

    def __is_context_changed(self):
        if self.ui.plainTextEdit.document().isModified():
            save_or_not = QMessageBox.warning(self, QApplication.translate("FileEditor", "save or discard", None,
                                                                           QApplication.UnicodeUTF8),
                                              QApplication.translate("FileEditor",
                                                                     "File is changed.Would you save it?",
                                                                     None, QApplication.UnicodeUTF8),
                                              QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
            if save_or_not == QMessageBox.Save:
                self.save()
                return False
            elif save_or_not == QMessageBox.Discard:
                return False
            else:
                return True
        else:
            return False

    def __set_format(self):
        # self.__format.setForeground(QColor(0x00, 0xff, 0xff))
        # self.__format.setBackground(QColor(0xff, 0x00, 0x00))
        # self.ui.plainTextEdit.mergeCurrentCharFormat(self.__format)
        pass

    def __set_title(self):
        self.setWindowTitle(self.__file_path + "[" + self.__file_encode + "]" + " @ " + self.__tittle)

    def __open(self, path):
        if path == "":
            return
        file_context = fileOpt.open_(path)
        file_encode = codeOpt.get_encoding(file_context)
        if len(file_context) > 5 and file_encode == "":
            QMessageBox.critical(self, QApplication.translate("FileEditor", "error", None,
                                                              QApplication.UnicodeUTF8),
                                 QApplication.translate("FileEditor",
                                                        "You are trying to open a binary file.",
                                                        None, QApplication.UnicodeUTF8),
                                 QMessageBox.Abort)
            return
        elif file_encode == "gb2312".upper() or file_encode == "gb2312".upper():
            file_encode = "GB18030"
        else:
            pass
        try:
            self.ui.plainTextEdit.setPlainText(unicode(file_context, file_encode))
        except Exception as ignore:
            file_encode = "utf-8"
            try:
                self.ui.plainTextEdit.setPlainText(unicode(file_context, file_encode))
            except Exception as e:
                file_encode = "GB18030"
                try:
                    self.ui.plainTextEdit.setPlainText(unicode(file_context, file_encode))
                except Exception as e:
                    self.except_(e)

        self.__file_encode = file_encode
        self.__file_path = path
        self.__set_title()
        try:
            self.ui.code.setCurrentIndex(self.__code_dict[self.__file_encode])
        except Exception as e:
            self.__code_dict[self.__file_encode] = len(self.__code_dict)
            self.ui.code.addItem(self.__file_encode)
            self.ui.code.setCurrentIndex(self.__code_dict[self.__file_encode])

    def __save(self, path):
        if self.__file_encode == "ascii":
            code = "utf-8"
        else:
            code = self.__file_encode
        text = self.ui.plainTextEdit.toPlainText()
        try:
            file_context = text.encode(code)
            fileOpt.save_(path, file_context)
            self.ui.statusbar.showMessage("saved as " + path)
        except Exception as e:
            self.except_(e)
        self.__set_title()
        pass

    # signal
    code_changed = Signal(str)
    filename_changed = Signal(str)
    excepted = Signal(Exception)
    opened = Signal(str)

    # Slot
    @Slot(Exception)
    def except_(self, e):
        self.ui.statusbar.showMessage(str(e))

    @Slot(str)
    def changeCode(self, code):
        self.__file_encode = code
        pass

    @Slot()
    def about(self):
        try:
            about = AboutDialog(self)
            about.show()
            self.ui.statusbar.showMessage("about")
        except Exception as e:
            self.except_(e)
        pass

    @Slot()
    def open(self):
        if self.__is_context_changed():
            return
        path = QFileDialog.getOpenFileName(self, "open", "./")[0]
        self.__open(path)
        self.opened.emit(path)
        pass

    @Slot()
    def saveas(self):
        path = QFileDialog.getSaveFileName(self, "save", "./")[0]
        self.__file_path = path
        self.__save(path)
        pass

    @Slot()
    def save(self):
        if self.__file_path == QApplication.translate("FileEditor", "unnamed", None, QApplication.UnicodeUTF8):
            self.saveas()
        else:
            self.__save(self.__file_path)
        pass

    @Slot()
    def new(self):
        if self.__is_context_changed():
            return
        self.ui.plainTextEdit.clear()
        self.__file_path = QApplication.translate("FileEditor", "unnamed", None, QApplication.UnicodeUTF8)
        self.__set_title()
        self.ui.statusbar.showMessage("created a new file")
        self.ui.code.setCurrentIndex(self.__code_dict[self.__file_encode])
        pass

    @Slot()
    def font(self):
        try:
            # font = QFontDialog.getFont(
            #     # initial=self.ui.plainTextEdit.font(),
            #     parent=self,
            #     title="font"
            # )
            # self.ui.plainTextEdit.setFont(font[0])
            # self.__font = font[0]
            # self.ui.statusbar.showMessage(str(font[0]))

            fdialog = QFontDialog(self)
            fdialog.setWindowTitle(QApplication.translate("FileEditor", "Select Font", None, QApplication.UnicodeUTF8))
            fdialog.setCurrentFont(self.__text_font)
            rs = fdialog.exec_()
            if QFontDialog.Accepted == rs:
                font = fdialog.selectedFont()
                self.ui.plainTextEdit.setFont(font)
                self.ui.statusbar.showMessage(font.family())
                self.__text_font = font
            else:
                pass
        except Exception as e:
            self.except_(e)
        pass

    @Slot()
    def find(self):
        # todo:
        find = FindDialog(self)
        find.exec_()
        pass

    @Slot()
    def replace(self):
        # self.ui.plainTextEdit.find()
        # todo:
        pass

    @Slot()
    def hehe(self, path):
        self.ui.statusbar.showMessage(path)

    # Event
    def resizeEvent(self, size):
        self.ui.plainTextEdit.resize(QSize(size.size().width(), size.size().height() - 50))

    def dragEnterEvent(self, event, *args, **kwargs):
        event.acceptProposedAction()

    def dropEvent(self, event, *args, **kwargs):
        if self.__is_context_changed():
            return
        self.__open(event.mimeData().urls()[0].toLocalFile())

    def closeEvent(self, event, *args, **kwargs):
        if self.__is_context_changed():
            event.ignore()
